package edu.example;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.*;


public class UserManager 
{
		
	private Reviewer currentReviewer;

	private Reviewer myReviewer;

	private boolean chairCheck;
	// if we use database, do we still need this value?  yes
	private Vector<Reviewer> ReviewerList;
	private Vector<String> dbreader = new Vector<String>();
	
	private Vector<String> header;
	
	
	
	//private File file;
	
	
	//Singleton UserManager
	public UserManager(/*File initFile*/)
	{ 
		//file = initFile;
		chairCheck = false;
		currentReviewer = null;
		ReviewerList = new Vector<Reviewer>();
		//dataProcessing(file);
		//loadU();
	}
	 
	// Accessors
	public Reviewer getCurrentUser(){
		return currentReviewer;
	}
	
	
	public Vector<Reviewer> getReviewerList() {return ReviewerList;}
	public boolean isChair()				  {return chairCheck;}
	
	// load from database
	public void loadUsers(String initName, String encrypted)
	{


		dbreader= new Vector<String>();
		try{
			Connection conn=ConnectionUtils.getConnection();		
		Statement s=conn.createStatement();
	    ResultSet rss=s.executeQuery("select * from reviewer where username='" + initName
	    		+ "'and password='" + encrypted +"'");
	    String reader = null;
        int column=1;
        if(rss.next()){
            while(column<14){
        	    reader = rss.getString(column);
        	    reader = new String(reader.getBytes("ISO-8859-1"),"GB2312");        	
                dbreader.addElement(reader);
                column++;
        	    }
            currentReviewer= new Reviewer(dbreader);
            chairCheck=currentReviewer.getChairCheck();
            System.out.println("user verified");
            ReviewerList.add(currentReviewer);
            
            
            PreparedStatement sss=conn.prepareStatement("select * from reviewer",
                    ResultSet.TYPE_SCROLL_SENSITIVE,
                    ResultSet.CONCUR_UPDATABLE);
    	    ResultSet rsss=sss.executeQuery();
    	    reader = null;
            if(rsss.next()){
            	rsss.beforeFirst();
            	while(rsss.next()){
            		dbreader=new Vector<String>();
            		if(currentReviewer.getName().equals(rsss.getString(1))){
            			return;
            		}
            		else{
            			for( column=1;column<14;column++){
            				reader = rsss.getString(column);
            				reader = new String(reader.getBytes("ISO-8859-1"),"GB2312");        	
            				dbreader.addElement(reader);                    
            	    		}
            			myReviewer= new Reviewer(dbreader);
            			ReviewerList.add(myReviewer);
            			System.out.println("+1");
            		}
            		System.out.println("all users information are loaded");
            	}
            }
            
            rsss.close();
	        rss.close();
	        conn.close();
            }
		}catch(Exception e){
    		e.printStackTrace();
    	}

		
		
		
		
		
		
		
		
		
		
		// for test
		/*Reviewer r1 = new Reviewer( "email", "chair", "bcd", true);
		r1.setHomeCountry1("China");
		r1.setHomeCountry2("");
		r1.setResearchArea1("Graphics and Visualization");
		r1.setResearchArea2("");
		r1.setResearchArea3("");
		ReviewerList.add(r1);
		
		Reviewer r2 = new Reviewer("email", "reviewer", "bcd", false);
		r1.setHomeCountry1("Brazil");
		r1.setHomeCountry2("Burkina");
		r1.setResearchArea1("Networks");
		r1.setResearchArea2("Security");
		r1.setResearchArea3("");
		ReviewerList.add(r2);
		*/
	}
	
	
	/*public void loadU(){
		Reviewer r1 = new Reviewer( "email", "chair", "bcd", true);
		r1.setHomeCountry1("China");
		r1.setHomeCountry2("");
		r1.setResearchArea1("Graphics and Visualization");
		r1.setResearchArea2("");
		r1.setResearchArea3("");
		ReviewerList.add(r1);
		
		Reviewer r2 = new Reviewer("email", "reviewer", "bcd", false);
		r2.setHomeCountry1("Brazil");
		r2.setHomeCountry2("Burkina");
		r2.setResearchArea1("Networks");
		r2.setResearchArea2("Security");
		r2.setResearchArea3("");
		ReviewerList.add(r2);
	}
	*/
	
	public void dataProcessing(File dataFile)
	{
		int lineCounter = 0;
		String word[] = null;
		try
		{
			FileInputStream fis = new FileInputStream(dataFile);
			DataInputStream din = new DataInputStream(fis);
			BufferedReader br = new BufferedReader(new InputStreamReader(din));
			String strLine;
			while ((strLine = br.readLine()) != null)   
			{
				Vector<String> CurrentDataEntry = new Vector<String>();
				TreeMap<String, String> CurrentData = new TreeMap<String, String>();
				
				for(int i = 0; i < strLine.length(); i++)
				{
					word = strLine.split("	");
				}

				if (lineCounter == 0 )
				{
					for(int i = 0; i < word.length; i++)
					{
						header.add(word[i]);
					}
				}
				else
				{
					for(int i = 0; i < word.length; i++)
						CurrentDataEntry.add(i, word[i]);
					for(int i = 0; i < header.size(); i++)
					{
						CurrentData.put(header.get(i), CurrentDataEntry.get(i));
					}
					
				}
			}
		}
		catch (Exception e)
		{
			System.err.println("Error: " + e.getMessage());
		}	
	}
	
	// save in the database
	public void saveUsers(){
		 
	}
	
	public boolean login(String initName, String initPassword){
		String passwordEncrypt = encrypt(initPassword);
		if (check(initName, passwordEncrypt))
			return true;
		else return false;
	}
	
	// encrypt the password the user entered
	public String encrypt(String initPassword){
		String encrypted = "";
		for (int i=0; i<initPassword.length(); i++){
			int temp = (int)(initPassword.toLowerCase().charAt(i))+1;
			encrypted += (char) temp;
		}
		return encrypted;
	}
	
	/** check with the password in the database
	 * if the user exists, then get the current reviewer
	 */
	public boolean check(String initName, String encrypted){
		boolean valid = false;
		try{
		    Connection conn=ConnectionUtils.getConnection();
		    Statement stmt=conn.createStatement();
		    ResultSet rs=stmt.executeQuery("select count(*) from reviewer where username='" + initName
		    		+ "'and password='" + encrypted +"'");
		    if(rs.next()){
		    	
		    	if(rs.getInt(1)>0){		    		
		    	    valid=true;
		    	    loadUsers(initName,encrypted);
		    	}
		    }
		    rs.close();
		    conn.close();
		    
		}catch(Exception e){
    		e.printStackTrace();
    	}		
		return valid;
	}
		
		/*
		
		for (int i=0; i<ReviewerList.size(); i++){
			String name = ReviewerList.get(i).getName();
			String password = ReviewerList.get(i).getPassword();
			boolean isChair = ReviewerList.get(i).getChairCheck();
			
			
			System.out.println("Name: "+name+"Password: "+password+" "+isChair);
			
			if (name.equals(initName)&& password.equals(encrypted)){
				if (isChair)
					chairCheck = true;
				currentReviewer = ReviewerList.get(i);
				return true;
			}
		}
		return false;
	}
	*/
	
	// update user info
	public void updateUser(Reviewer r){
		for (int i=0; i<ReviewerList.size(); i++)
			if (ReviewerList.get(i).getName().equals(r.getName())
					&& ReviewerList.get(i).getEMailAddress().equals(r.getEMailAddress()))
				ReviewerList.set(i, r);
		try{
		    Connection conn=ConnectionUtils.getConnection();
		    PreparedStatement s=conn.prepareStatement("select count(*) from reviewer where username= ?");
		    s.setString(1, r.getName());
		    ResultSet rs = s.executeQuery();
		    if(rs.next()){
		    	if(rs.getInt(1)>0){				  
		    		rs.close();
		    		PreparedStatement ss=conn.prepareStatement("DELETE from reviewer where username= ?");
		    		ss.setString(1, r.getName());
		    		int deletecount = ss.executeUpdate();
		    		System.out.println(deletecount + " row of user data is updated");
		    	}				    	    
		    }
	    
		    conn.setAutoCommit(false);
		    String checker;
		    PreparedStatement stmt = conn.prepareStatement("INSERT INTO reviewer VALUES (?, ?,?,?,?,?, ?,?,?,?,?, ?,?)");
	        
	        stmt.setString(1,  r.getName());
	        boolean ChairCheck=r.getChairCheck();
	        if(ChairCheck=true)
	        	stmt.setString(2,  "chair");
	        else stmt.setString(2,  "reviewer");
	        stmt.setString(3,  r.getPassword());
	        stmt.setString(4,  r.getEMailAddress());
	        stmt.setString(5,  r.getHomeCountry1());
	        stmt.setString(6,  r.getHomeCountry2());
	        stmt.setString(7,  r.getResearchArea1());
	        stmt.setString(8,  r.getResearchArea2());
	        stmt.setString(9,  r.getResearchArea3());	        
	        stmt.setString(10,  Integer.toString(r.getNumAssignedReviews()));
	        boolean availableCheck=r.getAvailable();
	        if(availableCheck=true)
	        	stmt.setString(11,  "true");
	        else stmt.setString(11,  "true");
	        stmt.setString(12,  Float.toString(r.getWorkload()));
	        stmt.setString(13,  Integer.toString(r.getCompletedReview()));
	        
	        //checker=CurrentDataEntry.get(i);
	       // if(checker==null)
	        	//stmt.setString(i+1,  "");    			        	
	    
	    stmt.addBatch();
	    //System.out.println(CurrentDataEntry.size());
	    // submit the batch for execution
        int[] updateCounts = stmt.executeBatch();
        conn.commit(); 
        conn.close();
		}catch(Exception e){
    		e.printStackTrace();
    	}	
	}
	
	// update the whole reviewer list
	public void setReviewerList(Vector<Reviewer> initReviewerList) {ReviewerList = initReviewerList;}
	

	// create assignments
	public void assignApplication(Vector<Reviewer> selectedReviewers, int totalApp)
	{
		if (selectedReviewers.size() != 0){
			float totalWorkload = 0;
			int left = totalApp;
			for (int i=0; i<selectedReviewers.size(); i++)
				totalWorkload += selectedReviewers.get(i).getWorkload();
			for (int i=0; i<selectedReviewers.size()-1; i++){
				selectedReviewers.get(i).setNumAssignedReviews((int)(3*totalApp*selectedReviewers.get(i).getWorkload()/totalWorkload));
				updateUser(selectedReviewers.get(i));
				left -= selectedReviewers.get(i).getNumAssignedReviews();
			}
			selectedReviewers.get(selectedReviewers.size()-1).setNumAssignedReviews(left);
		}
	}
	
	public void updateWorkload(Reviewer selectedReviewer, float initWorkload){
		selectedReviewer.setWorkload(initWorkload);
		updateUser(selectedReviewer);
	}
	
	public static void main(String[] args)
	{
		File file1 = new File("users.txt");
		//UserManager um = new UserManager(file1);
	}
}
